package services

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"unicode/utf8"

	"boomlive.com/boomlive-common/configs"
	"github.com/beego/beego/v2/core/logs"
)

// HttpCall 通用的调用HTTP接口的方法
// method: HTTP请求方法，如 "GET"、"POST" 等
// url: 要请求的URL地址
// headers: 请求头信息，以map[string]string形式传入
// body: 请求体数据，对于GET请求一般为空，对于POST等请求可传入相应数据，可为nil
// 返回值: 响应体数据（字节切片形式）和错误信息，如果请求成功且无错误，错误信息为nil
func HttpCall(method, url string, headers map[string]string, body interface{}) ([]byte, error) {
	// 创建HTTP客户端
	client := &http.Client{}

	// 创建请求对象
	var req *http.Request
	var err error

	// 根据请求方法处理请求体和创建请求对象
	if method == "GET" {
		req, err = http.NewRequest(method, url, nil)
	} else {
		// 将body转换为字节切片
		var bodyBytes []byte

		if body != nil {
			if bodyBytes, err = json.Marshal(body); err != nil {
				return nil, fmt.Errorf("序列化请求体失败: %v", err)
			}
		}
		logs.Info("请求体数据bodyBytes: %s", string(bodyBytes))
		req, err = http.NewRequest(method, url, bytes.NewBuffer(bodyBytes))
	}

	if err != nil {
		return nil, fmt.Errorf("创建请求对象失败: %v", err)
	}

	// 设置请求头
	for key, value := range headers {
		req.Header.Set(key, value)
	}

	// 发送请求
	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("发送请求失败: %v", err)
	}
	defer resp.Body.Close()

	// 读取响应体数据
	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, fmt.Errorf("读取响应体失败: %v", err)
	}
	logs.Info("响应体数据respBody: %s", string(respBody))

	// 根据响应状态码判断是否请求成功
	if resp.StatusCode != http.StatusOK {
		return respBody, fmt.Errorf("请求失败，状态码: %d，响应消息: %s", resp.StatusCode, string(respBody))
	}

	return respBody, nil
}

// TruncateString 截断字符串，如果字符串长度超过maxLength，则截断并加上"..."
func TruncateString(s string, maxLength int) string {
	if maxLength <= 0 {
		return ""
	}
	if utf8.RuneCountInString(s) <= maxLength {
		return s
	}
	runes := []rune(s)
	if maxLength > len(runes) {
		maxLength = len(runes)
	}
	truncated := runes[:maxLength]
	return string(truncated) + "..."
}

// CompleteURL 补全URL地址，如果URL地址不包含协议，则默认使用默认协议（http或https）
func CompleteURL(inputURL string) string {
	defaultDomain := configs.FileHost

	if inputURL == "" || inputURL == "null" {
		return ""
	}
	if strings.HasPrefix(inputURL, "http://") || strings.HasPrefix(inputURL, "https://") {
		return inputURL
	}
	if !strings.HasPrefix(inputURL, "/") {
		inputURL = "/" + inputURL
	}
	return defaultDomain + inputURL
}

// GetPathFromURL 获取URL中的路径部分
func GetPathFromURL(inputURL string) string {
	if inputURL == "" || inputURL == "null" {
		return ""
	}

	parsedURL, err := url.Parse(inputURL)
	if err != nil {
		return ""
	}
	pathFromURL := parsedURL.Path
	if !strings.HasPrefix(pathFromURL, "/") {
		pathFromURL = "/" + pathFromURL
	}
	return pathFromURL
}

// RemoveCommonElements 移除两个切片中的公共元素
func RemoveCommonElements[T comparable](slice1 []T, slice2 []T) []T {
	// 使用 map 存储 slice2 中的元素
	elementsToRemove := make(map[T]struct{})
	for _, elem := range slice2 {
		elementsToRemove[elem] = struct{}{}
	}

	// 存储不重复元素的新切片
	var result []T
	for _, elem := range slice1 {
		if _, exists := elementsToRemove[elem]; !exists {
			result = append(result, elem)
		}
	}
	return result
}

// SliceToString 将 []int64 切片元素用逗号拼接成字符串
func SliceToString(slice []int64) string {
	var builder strings.Builder
	for i, num := range slice {
		str := strconv.FormatInt(num, 10)
		if i > 0 {
			builder.WriteString(",")
		}
		builder.WriteString(str)
	}
	return builder.String()
}
